#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "encoder.h"

// 静态变量
static volatile EncoderState encoder_state = {0, ENCODER_STILL, ENCODER_BUTTON_RELEASED}; // 初始化状态
static volatile uint32_t last_tick = 0; // 上次更新计数的滴答计数
static volatile bool encoder_event_flag = false; // 编码器事件标志

// 编码器引脚
static int encoder_pin_a = -1;
static int encoder_pin_b = -1;
static int encoder_pin_k = -1;

// 停止时间阈值（滴答计数）
#define ENCODER_STOP_THRESHOLD pdMS_TO_TICKS(200) // 200ms

// GPIO中断服务函数
static void IRAM_ATTR encoder_isr_handler(void *arg) {
    uint32_t gpio_num = (uint32_t)arg;

    if (gpio_num == encoder_pin_a) {
        int a_state = gpio_get_level(encoder_pin_a);
        int b_state = gpio_get_level(encoder_pin_b);

        // 更新方向和计数
        if (a_state == b_state) {
            encoder_state.count++;
            encoder_state.direction = ENCODER_ROTATE_FORWARD; // 正转
        } else {
            encoder_state.count--;
            encoder_state.direction = ENCODER_ROTATE_BACKWARD; // 反转
        }

        // 更新滴答计数
        last_tick = xTaskGetTickCountFromISR();
        encoder_event_flag = true; // 设置事件标志
    } else if (gpio_num == encoder_pin_k) {
        int button_level = gpio_get_level(encoder_pin_k);
        if (button_level == 0) {
            encoder_state.button = ENCODER_BUTTON_PRESSED; // 按键按下
        } else {
            encoder_state.button = ENCODER_BUTTON_RELEASED; // 按键弹起
        }
        encoder_event_flag = true; // 设置事件标志
    }
}

// 初始化编码器
void encoder_init(int pin_a, int pin_b, int pin_k) {
    encoder_pin_a = pin_a;
    encoder_pin_b = pin_b;
    encoder_pin_k = pin_k;

    // 配置编码器通道 A 和 B
    gpio_config_t io_conf = {
        .intr_type = GPIO_INTR_ANYEDGE,  // 任意边沿触发中断
        .mode = GPIO_MODE_INPUT,        // 输入模式
        .pin_bit_mask = (1ULL << encoder_pin_a) | (1ULL << encoder_pin_b),
        .pull_up_en = GPIO_PULLUP_ENABLE,  // 上拉使能
    };
    gpio_config(&io_conf);

    // 配置按键引脚
    io_conf.intr_type = GPIO_INTR_ANYEDGE;  // 任意边沿触发中断
    io_conf.pin_bit_mask = (1ULL << encoder_pin_k);
    gpio_config(&io_conf);

    // 安装中断服务
    gpio_install_isr_service(0);
    gpio_isr_handler_add(encoder_pin_a, encoder_isr_handler, (void *)encoder_pin_a);
    gpio_isr_handler_add(encoder_pin_k, encoder_isr_handler, (void *)encoder_pin_k);

    // 初始化滴答计数
    last_tick = xTaskGetTickCount();
}

// 获取编码器状态
EncoderState *encoder_get_state(void) {
    // 检查是否停止
    uint32_t current_tick = xTaskGetTickCount();
    if (current_tick - last_tick > ENCODER_STOP_THRESHOLD) {
        encoder_state.direction = ENCODER_STILL; // 更新为停止状态
    }

    // 返回状态
    return (EncoderState *)&encoder_state;
}

// 重置计数
void encoder_reset_count(void) {
    encoder_state.count = 0;
    encoder_state.direction = ENCODER_STILL;
    encoder_state.button = ENCODER_BUTTON_RELEASED;
}

// 事件标志获取
bool encoder_get_event_flag(void) {
    bool flag = encoder_event_flag;
    encoder_event_flag = false; // 清除标志
    return flag;
}


